﻿using FastExecutor.Base.Config;
using FastExecutor.Design.Entity;
using FastIOC.Annotation;
using FastORM.Applicaiton;
using FastUtil.Extra;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web;

namespace FastExecutor.Base.Util
{
    [Component]
    public class AuthUtil
    {
        private string TokenPrefix = System.Configuration.ConfigurationManager.AppSettings["TokenPrefix"];
        private string SessionTimeOut = System.Configuration.ConfigurationManager.AppSettings["SessionTimeOut"];
        [AutoWired]
        public DBUtil @DBUtil;
        public string CreateTokenKey(string UserGuid)
        {
            DataTable userdt = @DBUtil.FindView(string.Format("select * from Frame_User where RowGuid='{0}'", UserGuid));
            DataTable oudt = @DBUtil.FindView(string.Format("select * from Frame_OU where RowGuid='{0}'", Convert.ToString(userdt.Rows[0]["OUGuid"])));
            string TokenKeyName = TokenPrefix + "_" + UserGuid + Guid.NewGuid().ToString();
            RedisUtil.SetHash(TokenKeyName, "UserGuid", Convert.ToString(userdt.Rows[0]["RowGuid"]));
            RedisUtil.SetHash(TokenKeyName, "DisplayName", Convert.ToString(userdt.Rows[0]["DisplayName"]));
            RedisUtil.SetHash(TokenKeyName, "LoginID", Convert.ToString(userdt.Rows[0]["LoginID"]));
            RedisUtil.SetHash(TokenKeyName, "Mobile", Convert.ToString(userdt.Rows[0]["Mobile"]));
            RedisUtil.SetHash(TokenKeyName, "EMail", Convert.ToString(userdt.Rows[0]["EMail"]));
            RedisUtil.SetHash(TokenKeyName, "OUGuid", Convert.ToString(userdt.Rows[0]["OUGuid"]));
            RedisUtil.SetHash(TokenKeyName, "OUName", Convert.ToString(oudt.Rows[0]["OUName"]));
            RedisUtil.SetHash(TokenKeyName, "OUCode", Convert.ToString(oudt.Rows[0]["OUCode"]));
            RedisUtil.SetHash(TokenKeyName, "ParentOUGuid", Convert.ToString(oudt.Rows[0]["ParentOUGuid"]));
            RedisUtil.SetKeyExpire(TokenKeyName, TimeSpan.FromMinutes(Convert.ToDouble(SessionTimeOut)));
            return TokenKeyName;
        }
        public bool ValidToken(string TokenKey)
        {
            bool Valid = true;
            try
            {
                if (!RedisUtil.ExistKey(TokenKey))
                {
                    Valid = false;
                }
                if (!RedisUtil.ExistHash(TokenKey, "UserGuid"))
                {
                    Valid = false;
                }

                string UserGuid = RedisUtil.GetHash(TokenKey, "UserGuid");
                if (UserGuid == null || string.IsNullOrEmpty(UserGuid))
                {
                    Valid = false;
                }
            }
            catch (Exception e)
            {

                Valid = false;
            }
            return Valid;
        }
        public TokenEntity GetToken(string TokenKey)
        {
            TokenEntity Entity = new TokenEntity();
            Dictionary<string, object> dic = RedisUtil.GetAllHash(TokenKey);
            Entity.UserGuid = Convert.ToString(dic["UserGuid"]);
            Entity.DisplayName = Convert.ToString(dic["DisplayName"]);
            Entity.LoginID = Convert.ToString(dic["LoginID"]);
            Entity.Mobile = Convert.ToString(dic["Mobile"]);
            Entity.EMail = Convert.ToString(dic["EMail"]);
            Entity.OUGuid = Convert.ToString(dic["OUGuid"]);
            Entity.OUName = Convert.ToString(dic["OUName"]);
            Entity.ParentOUGuid = Convert.ToString(dic["ParentOUGuid"]);
            Entity.ParentOUGuid = Convert.ToString(dic["ParentOUGuid"]);
            return Entity;
        }
        public TokenEntity GetToken()
        {
            string TokenKey = GetTokenString();
            if (!string.IsNullOrEmpty(TokenKey))
            {
                TokenEntity Entity = new TokenEntity();
                Dictionary<string, object> dic = RedisUtil.GetAllHash(TokenKey);
                Entity.UserGuid = Convert.ToString(dic["UserGuid"]);
                Entity.DisplayName = Convert.ToString(dic["DisplayName"]);
                Entity.LoginID = Convert.ToString(dic["LoginID"]);
                Entity.Mobile = Convert.ToString(dic["Mobile"]);
                Entity.EMail = Convert.ToString(dic["EMail"]);
                Entity.OUGuid = Convert.ToString(dic["OUGuid"]);
                Entity.OUName = Convert.ToString(dic["OUName"]);
                Entity.ParentOUGuid = Convert.ToString(dic["ParentOUGuid"]);
                Entity.ParentOUGuid = Convert.ToString(dic["ParentOUGuid"]);
                return Entity;
            }
            else
            {
                return null;
            }
        }
        public string GetTokenString(HttpRequestBase Request)
        {
            var cookies = Request.Cookies;
            HttpCookie cookie = cookies[TokenPrefix];
            if (cookie == null)
            {
                return string.Empty;
            }
            else
            {
                return cookie.Values["token"];
            }

        }
        public string GetTokenString()
        {
            var cookies = System.Web.HttpContext.Current.Request.Cookies;
            HttpCookie cookie = cookies[TokenPrefix];
            if (cookie == null)
            {
                return string.Empty;
            }
            else
            {
                return cookie.Values["token"];
            }

        }
        public void SetTokenCookie(HttpRequestBase Request, HttpResponseBase Reponse, string Token)
        {
            //存储cookie
            var cookies = Request.Cookies;
            HttpCookie cookie = cookies[TokenPrefix];
            if (null == cookie)
            {
                cookie = new HttpCookie(TokenPrefix);//初使化并设置Cookie的名称
                DateTime dt = DateTime.Now;
                TimeSpan ts = TimeSpan.FromMinutes(Convert.ToInt32(SessionTimeOut));
                cookie.Expires = dt.Add(ts);//设置过期时间
                cookie.Values.Add("token", Token);
                Reponse.AppendCookie(cookie);
            }
            else
            {
                cookie.Values.Set("token", Token);
            }
        }
        public bool ValidCookie(HttpRequestBase Request)
        {
            var cookies = Request.Cookies;
            HttpCookie cookie = cookies[TokenPrefix];
            if (null == cookie)
            {
                return false;
            }
            else
            {
                return true;
            }
        }
        public bool CheckIsAnonymousAccess(string Url)
        {
            bool flag = false;
            AnonymousAccessSection Section = (AnonymousAccessSection)ConfigurationManager.GetSection("AnonymousAccess");
            for (int i = 0; i < Section.Pages.Count; i++)
            {
                if (Url.Contains(Section.Pages[i].Url))
                {
                    flag = true;
                    break;
                }
            }
            return flag;
        }
        public void RemoveAuth(HttpRequestBase Request, HttpResponseBase Reponse)
        {
            var cookies = Request.Cookies;
            HttpCookie cookie = cookies[TokenPrefix];
            RedisUtil.DelteKey(cookie.Values["token"]);
            cookie.Expires = DateTime.Now.AddDays(-3);
            HttpContext.Current.Response.Cookies.Add(cookie);
        }
        public void RefreshAuth(HttpRequestBase Request, HttpResponseBase Reponse)
        {
            var cookies = Request.Cookies;
            HttpCookie cookie = cookies[TokenPrefix];
            cookie.Expires = DateTime.Now.AddMinutes(Convert.ToDouble(SessionTimeOut));
            Reponse.SetCookie(cookie);
            RedisUtil.SetKeyExpire(cookie.Values["token"], TimeSpan.FromMinutes(Convert.ToDouble(SessionTimeOut)));
        }
        public bool CheckIsModule(string Url)
        {
            string ModuleUrl = Url.Replace(CommonUtil.GetRootPath(), "");
            DataTable ModuletList = @DBUtil.FindView(string.Format(" select RowGuid from Frame_Module where  ModuleUrl='{0}'", ModuleUrl));
            if (ModuletList.Rows.Count > 0)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        public bool CheckModuleRight(string UGuid, string DGuid, string Url)
        {
            string ModuleUrl = Url.Replace(CommonUtil.GetRootPath(), "");
            DataTable RelationList = @DBUtil.FindView(string.Format(" select * from Frame_UserRolerelation where UserGuid='{0}'", UGuid));
            DataTable ModuletList = @DBUtil.FindView(string.Format(" select * from Frame_Module where  ModuleUrl='{0}'", ModuleUrl));
            string RoleListStr = "";
            if (RelationList.Rows.Count > 0)
            {
                RoleListStr = "(";
                foreach (DataRow item in RelationList.Rows)
                {
                    RoleListStr += string.Format("'{0}',", Convert.ToString(item["RoleGuid"]));
                }
                RoleListStr = RoleListStr.TrimEnd(',') + ")";
            }


            if (ModuletList.Rows.Count > 0)
            {
                string ModuleGuid = Convert.ToString(ModuletList.Rows[0]["RowGuid"]);
                //个人设置
                string UserSQL = string.Format(" RightGuid='{0}'", UGuid);
                //部门设置
                string OUSQL = string.Format(" RightGuid='{0}'", DGuid);
                //角色设置
                string RoleSQL = string.Format(" RightGuid in {0} ", RoleListStr);
                string RightSQL = string.Format(" and ModuleGuid='{0}'", ModuleGuid);
                if (!string.IsNullOrEmpty(RoleListStr))
                {
                    RightSQL += string.Format(" and (({0}) or ({1}) or ({2}))", UserSQL, OUSQL, RoleSQL);
                }
                else
                {
                    RightSQL += string.Format(" and (({0}) or ({1}))", UserSQL, OUSQL);
                }
                DataTable ModuleRightList = @DBUtil.FindView("select * from Frame_ModuleRight where 1=1 " + RightSQL);
                if (ModuleRightList.Rows.Count > 0)
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }
            else
            {
                return false;
            }
        }
    }
}
